#include "app/app_main.h"

#define HTTP_SERVER_ADDRESS  "10.57.101.129"
#define HTTP_SERVER_PORT 		 80

const char *url[] = {
	/*index 0*/
	"http://sky.manage/cgi-bin/detailedstatus/",
	NULL,
};

#define TRACE_LEVEL TRACE_LEVEL_DEBUG

/*定义http客户端线程栈大小*/
#define HTTP_CLIENT_STACK_SIZE 2048
/*定义http客户端线程句柄*/
static TX_THREAD       http_client_thread;

HttpClientContext httpClientContext;

static VOID http_thread_client_entry(ULONG thread_input);
static error_t httpClientGetRequest(const char *url,char_t buffer[],uint_t len);
static void parse_data(char_t buffer[],uint_t len);

void app_http_client_thread_create(VOID *first_unused_memory)
{
	UINT            status;
	char *pointer = TX_NULL;
	
	if(first_unused_memory == TX_NULL) { return ; }
	
	/* Allocate the stack for thread 1.  */
	tx_byte_allocate(first_unused_memory, (VOID **) &pointer, HTTP_CLIENT_STACK_SIZE, TX_NO_WAIT);
	if(pointer == TX_NULL)
	{
		PRINTF_Dbg("allocate http client thread stack failed..\r\n");
		
		return ;
	}
	/* Create the HTTP Client thread. */
	status = tx_thread_create(&http_client_thread, "HTTP Client", http_thread_client_entry, 0,  
									 pointer, HTTP_CLIENT_STACK_SIZE, 
									 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
	if(status)
	{
		PRINTF_Dbg("create http client thread failed..\r\n");
		
		return ;
	}
}

static VOID http_thread_client_entry(ULONG thread_input)
{
	char *buffer = TX_NULL;
	const uint_t len = 1024;
	
	while(netTaskRunning != TRUE)
	{
		tx_thread_sleep(100);
	}
	
	for(;;)
	{
		while(netGetLinkState(netInterface) != TRUE)
		{
			tx_thread_sleep(500);
		}
		
		tx_byte_allocate(thread_get_pool(), (VOID **) &buffer, len, TX_NO_WAIT);
		if(buffer == TX_NULL)
		{
			PRINTF_Dbg("allocate buffer failed..\r\n");
			
			break;
		}
		
		httpClientGetRequest(url[0],buffer,len);
		parse_data(buffer,len);
		
		tx_byte_release(buffer);
		
		tx_thread_sleep(5000);
	}
	
	tx_thread_delete(tx_thread_identify());
}

static error_t httpClientGetRequest(const char *url,char_t buffer[],uint_t len)
{
	error_t error;
	size_t length;
	uint_t status;
	const char_t *value;
	IpAddr ipAddr;
	
	//Initialize HTTP client context
	httpClientInit(&httpClientContext);
	
	do {
		//Debug message
		TRACE_INFO("\r\n\r\nResolving server name...\r\n");

		//Select HTTP protocol version
		error = httpClientSetVersion(&httpClientContext, HTTP_VERSION_1_1);
		//Any error to report?
		if(error)
			 break;

		//Set timeout value for blocking operations
		error = httpClientSetTimeout(&httpClientContext, 20000);
		//Any error to report?
		if(error)
			 break;

		ipAddr.length = sizeof(Ipv4Addr);
		ipv4StringToAddr(HTTP_SERVER_ADDRESS, &ipAddr.ipv4Addr);

		//Debug message
		TRACE_INFO("Connecting to HTTP server %s...\r\n",
			 ipAddrToString(&ipAddr, NULL));
		
		//Connect to the HTTP server
		error = httpClientConnect(&httpClientContext, &ipAddr, HTTP_SERVER_PORT);
		//Any error to report?
		if(error)
		{
			//Debug message
			TRACE_INFO("Failed to connect to HTTP server!\r\n");
			break;
		}

		//Create an HTTP request
		httpClientCreateRequest(&httpClientContext);
		httpClientSetMethod(&httpClientContext, "GET");
		httpClientSetUri(&httpClientContext, url);

		//Send HTTP request header
		error = httpClientWriteHeader(&httpClientContext);
		//Any error to report?
		if(error)
		{
			 //Debug message
			 TRACE_INFO("Failed to write HTTP request header!\r\n");
			 break;
		}

		//Receive HTTP response header
		error = httpClientReadHeader(&httpClientContext);
		//Any error to report?
		if(error)
		{
			 //Debug message
			 TRACE_INFO("Failed to read HTTP response header!\r\n");
			 break;
		}

		//Retrieve HTTP status code
		status = httpClientGetStatus(&httpClientContext);
		//Debug message
		TRACE_INFO("HTTP status code: %u\r\n", status);

		//Retrieve the value of the Content-Type header field
		value = httpClientGetHeaderField(&httpClientContext, "Content-Type");

		//Header field found?
		if(value != NULL)
		{
			 //Debug message
			 TRACE_INFO("Content-Type header field value: %s\r\n", value);
		}
		else
		{
			 //Debug message
			 TRACE_INFO("Content-Type header field not found!\r\n");
		}

		//Receive HTTP response body
		while(!error)
		{
			 //Read data
			 error = httpClientReadBody(&httpClientContext, buffer,
					len - 1, &length, 0);

			 //Check status code
			 if(!error)
			 {
					//Properly terminate the string with a NULL character
					buffer[length] = '\0';
					//Dump HTTP response body
					TRACE_INFO("%s", buffer);
			 }
		}

		//Terminate the HTTP response body with a CRLF
		TRACE_INFO("\r\n");

		//Any error to report?
		if(error != ERROR_END_OF_STREAM)
			 break;

		//Close HTTP response body
		error = httpClientCloseBody(&httpClientContext);
		//Any error to report?
		if(error)
		{
			 //Debug message
			 TRACE_INFO("Failed to read HTTP response trailer!\r\n");
			 break;
		}

		//Gracefully disconnect from the HTTP server
		httpClientDisconnect(&httpClientContext);

		//Debug message
		TRACE_INFO("Connection closed\r\n");
		
	} while(0);
	
	//Release HTTP client context
	httpClientDeinit(&httpClientContext);
	
	return error;
}

static void parse_data(char_t buffer[],uint_t len)
{
	
}
